using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Xml.Serialization;
using SoulSolutions.Cluster.JavaScriptControl;

public static class PostcodeData
{
    public static List<ClusteredPin> GetVisiblePins(Bounds bounds)
    {
        //get all postocdes from xml file
        List<location> postcodeList = getAll();
        //get only those with the bounds supplied
        LocationFinder finder = new LocationFinder(bounds);
        List<location> postcodesinbounds = postcodeList.FindAll(finder.FindByBounds);
        //transform into a set of pins
        List<ClusteredPin> postcodepins = new List<ClusteredPin>();
        foreach (location location in postcodesinbounds)
        {
            postcodepins.Add(new ClusteredPin(new LatLong(location.lat, location.lon), new Bounds(new LatLong(location.lat, location.lon), new LatLong(location.lat, location.lon))));
        }
        return postcodepins;
    }

    public static MapData GetPinsbyBounds(Bounds bounds, int startIndex, int quantity)
    {
        //get all postocdes from xml file
        List<location> postcodeList = getAll();
        //get only those with the bounds supplied
        LocationFinder finder = new LocationFinder(bounds);
        List<location> postcodesinbounds = postcodeList.FindAll(finder.FindByBounds);
        //get correct index, records and transform into pindata list
        List<PinData> Items = new List<PinData>();
        for (int x = startIndex; x < (startIndex + quantity); x++ )
        {
            //shortcut if end of list
            if (x >= postcodesinbounds.Count) break;

            //populte pindata
            Items.Add(new PinData(postcodesinbounds[x].postcode, postcodesinbounds[x].title, new LatLong(postcodesinbounds[x].lat, postcodesinbounds[x].lon)));
        }
        return new MapData(postcodesinbounds.Count, Items);
    }

    private static List<location> getAll()
    {
        string cacheKey = "postcodes.xml";
        //first check if data is in the cache
        List<location> result = (List<location>) HttpRuntime.Cache.Get(cacheKey);
        if (result == null) //if not then parse data from XML file
        {
            XmlSerializer serializer = new XmlSerializer(typeof (locations));
            string filepath = HttpContext.Current.Server.MapPath("~/data/") + cacheKey;
            TextReader reader = new StreamReader(filepath);
            try
            {
                locations ev = (locations) serializer.Deserialize(reader);
                result = new List<location>();
                result.AddRange(ev.location);
                //cache result for future requests - file dependency so if file is modified the cache is invalidated
                HttpRuntime.Cache.Add(cacheKey, result, new CacheDependency(filepath), DateTime.MaxValue, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }
            finally
            {
                reader.Close();
            }
        }
        return result;
    }
}